/*
每张图片都有对应的数字，是1到10.
我用map[][]二维数组记录这些数字.
然后用animal[]一维数组来记录图片的地址.
用图片时取animal的下标map[][].
鼠标的坐标是begin.row,begin.col,end.row,end.col.
*/
#include <stdio.h>
#define MAP_SIZE 10//每一行有多少张图片
#include <graphics.h>
#include <conio.h>
#include "EasyXPng.h"
#include <vector>
#define MAP_SIZE 10//每一行有多少张图片
#define length 600
#define height 600
int map[MAP_SIZE+2][MAP_SIZE+2];
IMAGE im_show;//当前时刻要显示的图像
IMAGE tip;
IMAGE animal[11];
//鼠标变量
struct index
{
	int row;
	int col;
}begin = {-1,-1},end = {-1,-1},tip_mouse = {-1,-1},a = {-1,-1},b = {-1,-1};
//保存点击状态
enum Cur
{
	BEGIN,
	END
};
Cur state = BEGIN;
//游戏图形绘制
void gameDraw() 
{
	int i,j;
	loadimage(&im_show,"res\\背景.jpg",length,height);
	putimage(0,0,&im_show);
	loadimage(&tip,"res\\tip.jpg",length/12,height/12);
	putimage(11*length/12,0,&tip);
	//loadimage(&tip,"res\\tip.jpg",length/12,height/12);
	//putimage(11*length/12,0,&tip);
	char filename[20];
	for (i = 1; i < 11; i++)
	{
		for (j = 1; j < MAP_SIZE+1; j++)
			sprintf(filename,"res\\%d.jpg",i);
		loadimage(&animal[i],filename,length/12,height/12);
	}
	for (i = 1; i < 11; i++)
	{
		for (j = 1; j < 11; j++)
		{
			if (map[i][j] != 0)
			{
				putimage(j*50,i*50,&animal[map[i][j]]);
			}
		}
	}
}
//用不同的数据表示不同的动物，每种动物10个，共10种动物
void gameInit()
{
	int i,j;
	for (i = 1; i < MAP_SIZE+1; i++)
	{
		for (j = 1; j < MAP_SIZE+1; j++)
		{
			map[i][j] = i;
		}
	}
}
//获取鼠标消息，获取点击的两个位置的下标
void mouseEvent()
{
	if (MouseHit())
	{
		MOUSEMSG msg = GetMouseMsg();
		//判断鼠标点击的位置（begin，end），第一次点击？第二次点击？
		if (msg.uMsg == WM_LBUTTONDOWN)
		{
			int col = msg.x/(length/12);
			int row = msg.y/(height/12);
			if (col == 11 && row == 0)
			{
				tip_mouse.col = 11;
				tip_mouse.row = 0;
			}
			else
			{
				if (msg.uMsg == WM_LBUTTONDOWN && state == BEGIN)
				{
					//把鼠标的坐标转成对应的数组的下标
					int col = msg.x/(length/12);
					int row = msg.y/(height/12);
					begin.row = row;
					begin.col =col;
					state = END;
				}
				else if (msg.uMsg == WM_LBUTTONDOWN && state == END)
				{
					int col = msg.x/(length/12);
					int row = msg.y/(height/12);
					end.row = row;
					end.col =col;
					state = BEGIN;
				}  
				tip_mouse.row = -1;
				tip_mouse.col = -1;
			}
		}
	}
}
//水平方向
bool horizon(struct index begin,struct index end)
{
	bool detect;
	detect = true;
	int i;
	if (begin.row != end.row)
	{
		return false;
	}
	else
	{
		if (begin.col < end.col)
		{
			for (i = begin.col+1; i < end.col; i++)
			{
				if (map[begin.row][i] != 0)
				{
					detect = false;
					break;
				}
			}
		}
		else
		{
			for (i = end.col+1; i < begin.col; i++)
			{
				if (map[begin.row][i] != 0)
				{
					detect = false;
					break;
				}
			}
		}
		if (map[begin.row][begin.col] != map[end.row][end.col])
		{
			detect = false;
		}
	}
	return detect;
}
//水平方向应用
bool horizon_apply(struct index begin,struct index end)
{
	bool detect;
	detect = true;
	int i;
	if (begin.row != end.row)
	{
		return false;
	}
	else
	{
		if (begin.col < end.col)
		{
			for (i = begin.col+1; i < end.col; i++)
			{
				if (map[begin.row][i] != 0)
				{
					detect = false;
					break;
				}
			}
		}
		else
		{
			for (i = end.col+1; i < begin.col; i++)
			{
				if (map[begin.row][i] != 0)
				{
					detect = false;
					break;
				}
			}
		}
	}
	return detect;
}
//竖直方向
bool vertical(struct index begin,struct index end)
{
	bool detect;
	detect = true;
	int i;
	if (begin.col != end.col)
	{
		return false;
	}
	else
	{
		if (begin.row < end.row)
		{
			for (i = begin.row+1; i < end.row; i++)
			{
				if (map[i][begin.col] != 0)
				{
					detect = false;
					break;
				}
			}
		}
		else
		{
			for (i = end.row+1; i < begin.row; i++)
			{
				if (map[i][begin.col] != 0)
				{
					detect = false;
					break;
				}
			}
		}
		if (map[begin.row][begin.col] != map[end.row][end.col])
		{
			detect = false;
		}
	}
	return detect;
}
//竖直方向应用
bool vertical_apply(struct index begin,struct index end)
{
	bool detect;
	detect = true;
	int i;
	if (begin.col != end.col)
	{
		return false;
	}
	else
	{
		if (begin.row < end.row)
		{
			for (i = begin.row+1; i < end.row; i++)
			{
				if (map[i][begin.col] != 0)
				{
					detect = false;
					break;
				}
			}
		}
		else
		{
			for (i = end.row+1; i < begin.row; i++)
			{
				if (map[i][begin.col] != 0)
				{
					detect = false;
					break;
				}
			}
		}
	}
	return detect;
}
//一次转角
bool once(struct index begin,struct index end)
{
	if (begin.row == end.row || begin.col == end.col)
	{
		return false;
	}
	else
	{
		bool detect;
		bool detect1,detect2,detect3;
		detect = true;
		detect1 = true;
		detect2 = true;
		detect3 = true;
		int i,k;
		struct index t;
		t.col = end.col;
		t.row = begin.row;
		if (horizon_apply(t,begin) == true && vertical_apply(t,end) == true && map[t.row][t.col] == 0) 
		{
			detect1 = true;
		}
		else
		{
			detect1 = false;
		}
		t.col = begin.col;
		t.row = end.row;
		if (horizon_apply(t,end) == true && vertical_apply(t,begin) == true && map[t.row][t.col] == 0)
		{
			detect2 = true;
		}
		else
		{
			detect2 = false;
		}
		if (detect1 == true || detect2 == true)
		{
			detect = true;
		}
		else
		{
			detect = false;
		}
		if (map[begin.row][begin.col] != map[end.row][end.col])
		{
			detect = false;
		}
		return detect;
	}
}
//一次转角应用
bool once_apply(struct index begin,struct index end)
{
	if (begin.row == end.row || begin.col == end.col)
	{
		return false;
	}
	else
	{
		bool detect;
		bool detect1,detect2,detect3;
		detect = true;
		detect1 = true;
		detect2 = true;
		detect3 = true;
		int i,k;
		struct index t;
		t.col = end.col;
		t.row = begin.row;
		if (horizon_apply(t,begin) == true && vertical_apply(t,end) == true && map[t.row][t.col] == 0) 
		{
			detect1 = true;
		}
		else
		{
			detect1 = false;
		}
		t.col = begin.col;
		t.row = end.row;
		if (horizon_apply(t,end) == true && vertical_apply(t,begin) == true && map[t.row][t.col] == 0)
		{
			detect2 = true;
		}
		else
		{
			detect2 = false;
		}
		if (detect1 == true || detect2 == true)
		{
			detect = true;
		}
		else
		{
			detect = false;
		}
		return detect;
	}
}
//两次转角
bool twice(struct index begin,struct index end)
{
	bool detect;
	bool detect4,detect3,detect_1,detect_2;
	detect = true;
	detect4 = true;
	detect_1 = false;
	detect_2 = false;
	int i,j,k,l;
	struct index t,m;
	for (j = 1; j < 11; j++)
	{
		if(j == end.col)
		{
			continue;
		}
		m.col = j;
		m.row = end.row;
		if (horizon_apply(m,end) == true && map[m.row][m.col] == 0)
		{
			detect3 = true;
		}
		else
		{
			detect3 = false;
		}
		if (detect3 == true)
		{
			if (once_apply(m,begin) == true)
			{
				detect_1 = true;
				break;
			}
		}
	}
	for (j = 1; j < 11; j++)
	{
		if (j == end.row)
		{
			continue;
		}
		m.row = j;
		m.col = end.col;
		if (vertical_apply(m,end) == true && map[m.row][m.col] == 0)
		{
			detect3 = true;
		}
		else
		{
			detect3 = false;
		}
		if (detect3 == true)
		{
			if (once_apply(m,begin) == true)
			{
				detect_2 = true;
				break;
			}
		}
	}	
	if (detect_1 == true || detect_2 == true)
	{
		detect = true;
	}
	else
	{
		detect = false;
	}
	if (map[begin.row][begin.col] != map[end.row][end.col])
	{
		detect = false;
	}
	return detect;	
}
//如何判断能否消除begin和end两个动物
bool erase(struct index begin,struct index end)
{
	bool m;
	m = false;
	//首先判断点击的是不是同一个
	if (begin.row == end.row && begin.col == end.col)
	{
		return false;
	}
	else
	{
		//1，水平方向消除
		m = horizon(begin,end);
		if (m == true)
		{
			return true;
		}
		//2，垂直方向消除
		m = vertical(begin,end);
		if (m == true)
		{
			return m;
		}
		//3,一个转角消除
		m = once(begin,end);
		if (m == true)
		{
			return m;
		}
		//4,两个转角消除
		m = twice(begin,end);
		if (m == true)
		{
			return m;
		}
	}
	return m;
}
//包括边界一起输出（数据）
void showMAP()
{
	int i = 0,j = 0;
	for (i = 0; i < MAP_SIZE+2; i++)
	{
		for (j = 0; j < MAP_SIZE+2; j++)
		{
			printf("%-2d ",map[i][j]);
		}
		printf("\n");
	}
}
//递推写随机数
int random(int cnt[])
{
	int m = rand()%10+1;
	int i,j;
	if (cnt[m] < 10)
	{
		cnt[m]++;
	}
	else
	{
		m = random(cnt);
	}
	return m;
}
//打乱数组
void disturb()
{
	int i,j;
	int m,cnt[11] = {0};
	for (i = 1; i < 11; i++)
	{
		for (j = 1; j < 11; j++)
		{
			map[i][j] = random(cnt);
		}
	}
}
void link()
{
	int t = 1;
	if (tip_mouse.col != -1 && tip_mouse.row != -1 )
	{
		int i,j,k,l;
		for (i = 1; i < 11; i++)
		{
			for (j = 1; j < 11; j++)
			{
				a.row = i;
				a.col = j;
				for (k = 1; k < 11; k++)
				{
					for (l = 1; l < 11; l++)
					{
						b.row = k;
						b.col = l;
						if (erase(a,b) == true && map[b.row][b.col] != 0)
						{
							rectangle(a.col*length/12,a.row*length/12,(a.col+1)*length/12,(a.row+1)*length/12);
							rectangle(b.col*length/12,b.row*length/12,(b.col+1)*length/12,(b.row+1)*length/12);
							t = 0;
							break;
						}
					}
					if (t == 0)
					{
						break;
					}
				}
				if (t == 0)
				{
					break;
				}
			}
			if (t == 0)
			{
				break;
			}
		}
	}
}
int main()
{
	//创建一个图形窗口
	initgraph(length,height);
	gameInit();
	disturb();
	showMAP();
	while (1)
	{
		//开始双缓冲绘图
		BeginBatchDraw();
		gameDraw();
		link();
		rectangle(begin.col*length/12,begin.row*length/12,(begin.col+1)*length/12,(begin.row+1)*length/12);
		rectangle(end.col*length/12,end.row*length/12,(end.col+1)*length/12,(end.row+1)*length/12);
		//结束双缓冲绘图
		EndBatchDraw();
		mouseEvent();
		if (erase(begin,end) && begin.row != -1 && end.row != -1 && begin.col != -1 && end.col != -1)
		{
			map[begin.row][begin.col] = 0;
			map[end.row][end.col] = 0;
		}	
	}  
	_getch();
	return 0;
}